package com.Jano.dao.Impl;


import com.Jano.util.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.SQLException;
import java.util.List;

public abstract class AbstractDaoImpl {
    private final QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());


    /**
     * 对QueryRunner中的query方法进行二次封装，主要对其中的异常进行了集中处理，不需要
     * 每个Dao方法中都用try……catch……去处理了
     * @param sql
     * @param resultSetHandler
     * @param params
     * @param <T>
     * @return
     */
    private <T> T query(String sql, ResultSetHandler<T> resultSetHandler, Object... params) {
        try {
            return runner.query(sql, resultSetHandler, params);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("数据库异常...");
        }
    }

    /**
     * 专门用于查询对象列表的方法，即BeanListHandler情况下的查询
     * @param sql
     * @param params
     * @param <T>
     * @return
     */
    protected <T> List<T> queryForList(String sql, Class<T> clazz, Object... params) {
        return query(sql, new BeanListHandler<>(clazz), params);
    }

    /**
     * 专门用于查询某个列值对应列表方法，即ColumnListHandler情况下的查询
     * @param sql
     * @param params
     * @param <T>
     * @return
     */
    protected <T> List<T> queryForColumnList(String sql, Object... params) {
        return query(sql, new ColumnListHandler<>(), params);
    }

    /**
     * 专门用于查询单个对象的方法，即BeanHandler情况下的查询
     * @param sql
     * @param params
     * @param <T>
     * @return
     */
    protected <T> T queryForObject(String sql, Class<T> clazz, Object... params) {
        return query(sql, new BeanHandler<>(clazz), params);
    }


    /**
     * 专门用于标量的方法，即ScalarHandler情况下的查询
     * @param sql
     * @param params
     * @param <T>
     * @return
     */
    protected <T> T queryForValue(String sql, Object... params) {
        return query(sql, new ScalarHandler<>(), params);
    }

    /**
     * 专门用于做DML操作的方法
     * @param sql
     * @param params
     * @return
     */
    protected boolean update(String sql, Object... params) {
        try {
            return runner.update(sql, params) > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("数据库异常...");
        }
    }

}
